using System;
using System.IO;
using System.Web;
using System.Xml;
using System.Text;
using System.Xml.Serialization;
using SharePoint.ImportExport.Core;
using GotDotNet.SharePointExtractor;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Utilities;
using Microsoft.SharePoint.Portal;
using Microsoft.SharePoint.Portal.SiteData;
using Microsoft.SharePoint.Portal.Security;
using Microsoft.SharePoint.Portal.Topology;
using GotDotNet.SharePointExtractor.Common;
using System.Collections;

namespace GotDotNet.SharePointExtractor.Portal
{
	/// <summary>
	/// Summary description for Wrapper.
	/// </summary>
	public class PortalWrapper
	{
		#region Private members
		private PortalContext ThisPortalContext=null;
		#endregion
		SPWeb thisWeb=null;
		SharePoint.ImportExport.Core.ListTemplatesList listtemplates=null;
		static int nrOfListItems=0;
		static int nrOfDocuments=0;
		public PortalWrapper()
		{
			

		}
		
		/// <summary>
		/// This method open the portal specified by the siteUrl parameter
		/// </summary>
		/// <param name="portalUri"></param>
		/// <returns></returns>
		public bool OpenPortal(Uri portalUri)
		{
			Logger.Log(ErrorLevel.Information, "Opening the portal specified by "+portalUri.ToString());
			bool bOK=false;
			
			TopologyManager topology = new TopologyManager();
			PortalSite portalSite = topology.PortalSites[portalUri];
			if(null!=portalSite)
			{
				ThisPortalContext = PortalApplication.GetContext(portalSite);
				bOK=true;
			}
			return bOK;

		}
		
		#region Portal
		/// <summary>
		/// This method returns the ID of the Portal area specified by the rootArea parameter
		/// This parameter can point to a hierarchy root, e.g. http://server/Topics or further down eg http://server/Topics/SubArea/SubSubArea
		/// </summary>
		/// <param name="rootArea"></param>
		/// <returns></returns>
		public Guid GetSystemAreaGuid(string rootArea)
		{
			rootArea=rootArea.Replace("%20"," ");
			string [] areas=rootArea.Split("/".ToCharArray());
			Guid returnGuid=Guid.Empty;
			try
			{
				Area area=null;
				try
				{
					SystemArea sysArea = (SystemArea)Enum.Parse(typeof(SystemArea), areas[0],true);
					Guid guid = AreaManager.GetSystemAreaGuid(ThisPortalContext, sysArea );
					area=AreaManager.GetArea(ThisPortalContext,guid);
					Logger.Log(ErrorLevel.Information,"Starting to resolve the area from the \""+area.Title+"\" area");
				
				}
				catch(ArgumentException argEx)
				{
					//Check from home -- as rootArea might be renamed or we might be importing elsewhere

					Logger.Log(ErrorLevel.Information,"Starting to resolve the area from the \"Home\" area");

					SystemArea eSysArea = SystemArea.Home;
		
					Guid eGuid = AreaManager.GetSystemAreaGuid(ThisPortalContext, eSysArea);
					area=AreaManager.GetArea(ThisPortalContext,eGuid);
					if(areas[0].Length>0)
						area=area.Areas[areas[0]];
				}

				
				for(int i=1;i<areas.Length;i++)
				{
					Logger.Log(ErrorLevel.Information,"Resolving the area \""+areas[i]);
					area=area.Areas[areas[i]];
				}
				if(area.ID!=Guid.Empty)
				
					returnGuid=area.ID;
			}

			catch(NullReferenceException NullEx)
			{
				Logger.Log(ErrorLevel.Error,"Could not resolve the area "+rootArea+". Error: "+NullEx .Message);
			}
			catch(ArgumentException ArgEx)
			{
				Logger.Log(ErrorLevel.Error,"Could not resolve the area "+rootArea+". Error: "+ArgEx.Message);
			}
			return returnGuid;

		}

		#endregion
        public string Process(string siteURL, string outputDirectory, string rootContainerName, string areaName, bool extractUsers, string listName, string folderName, bool includeSubWebs, bool extractDesign, DateTime threshold, bool extractVersions, ListTemplatesList listTemplates, SiteType extractAsType, Hashtable excludedProperties)
		{
			listtemplates=listTemplates;
			if(extractAsType==SiteType.Undefined)
				extractAsType=SiteType.Area;
			//Open the Home AreaWeb
			TopologyManager topologyManager = new TopologyManager();
			Uri uri = new Uri(siteURL);
			Uri spUri=new Uri(uri.Scheme+"://"+uri.Authority);
								
			PortalSite portalSite = topologyManager.PortalSites[spUri];
			if(null!=portalSite)
			{
				ThisPortalContext= PortalApplication.GetContext(portalSite);
									
			}
			Guid homeGuid = Guid.Empty;
								
			if(uri.LocalPath.Length>1)
				homeGuid = GetSystemAreaGuid(Microsoft.SharePoint.Utilities.SPEncode.UrlDecodeAsUrl(uri.LocalPath.Substring(1)));
			else
			{
				Logger.Log(ErrorLevel.Information,"Starting to resolve the area from the \"Home\" area");
				//Check from home -- as rootArea might be renamed or we might be importing elsewhere
				SystemArea eSysArea = SystemArea.Home;
		
				homeGuid = AreaManager.GetSystemAreaGuid(ThisPortalContext, eSysArea);
			}


			Area thisArea = AreaManager.GetArea(ThisPortalContext, homeGuid);
			Logger.Log(ErrorLevel.Information,"Area \""+thisArea.Title+"\" opened");
			SPWeb web = thisArea.Web;
			Directory.CreateDirectory(outputDirectory);
			Directory.SetCurrentDirectory(outputDirectory);
			web.Lists.IncludeRootFolder=true;
			
			AreaCollection subareas = thisArea.Areas;
			
			//Create a new instance of the Import class
			SharePoint.ImportExport.Core.Import import = new Import();
			import.Settings.Locale=web.Locale.LCID.ToString();
					    
			RootContainer rootContainer= new RootContainer();
			rootContainer.Type=extractAsType;
			rootContainer.Name=rootContainerName; 
			
			//This class is the actual site that will be created
			SharePoint.ImportExport.Core.Container container= new Container();
			import.RootContainers.Add(rootContainer);
			
			container.Name=areaName;
			container.Owner=thisArea.Owner;
			container.Contact=thisArea.OwnerEmail;
			container.Description=thisArea.Description;
			container.Type=extractAsType;
			if(extractAsType==SiteType.Site)
				container.Template="STS#0";
			else
				container.Template =thisArea.AreaTemplate;
			if(extractUsers)
			{
				if(extractAsType==SiteType.Site)
				{
				
					container.InheritPermissions=web.Permissions.Inherited;
					//Add users
					foreach(SPUser spuser in web.Users)
					{
						SharePoint.ImportExport.Core.User user= new SharePoint.ImportExport.Core.User();
						user.Account=spuser.LoginName;
						StringBuilder sb=new StringBuilder();
					
						foreach(SPRole role in spuser.Roles)
						{
							sb.Append(role.Name);
							sb.Append(",");
						}
                        sb.Remove(sb.Length - 1, 1);
						if(sb.Length>0)
						{
							user.Role=sb.ToString();
							user.Email=spuser.Email;
							string userName="";
							if(null==spuser.Name)
							{
								userName=spuser.LoginName;
							}
							else
							{
								if(0==spuser.Name.Length)
									user.Name=spuser.LoginName;
								else
									user.Name=spuser.Name;
							}
							if(spuser.IsDomainGroup)
								user.Type="Group";
							else
								user.Type="Person";
							container.Security.Users.Add(user);
						}
					}
				
				}
				else
				{
			
					// Collect the SPS permissions
					// done here in a portal rather than at the site/subsite level like WSS
					PermissionCollection spc = SecurityManager.ManageSiteSecurity(ThisPortalContext);
					foreach(Permission pm in spc)
					{
						Microsoft.SharePoint.Portal.Security.User spuser = pm.Member as Microsoft.SharePoint.Portal.Security.User;
						Microsoft.SharePoint.Portal.Security.Role sprole = pm.Member as Microsoft.SharePoint.Portal.Security.Role;
						if (spuser!=null)
						{
							SharePoint.ImportExport.Core.User user = new SharePoint.ImportExport.Core.User();
							user.Email=spuser.Email;
							user.Account=spuser.LoginName;
							user.Xml=spuser.Xml;
							user.Permissions=pm.PortalMask.ToString();
							container.Security.Users.Add(user);
						}
						else if (sprole!=null)
						{
							SharePoint.ImportExport.Core.Role role = new SharePoint.ImportExport.Core.Role();
							role.RoleName=sprole.Name;
							role.Xml=sprole.Xml;
							role.Permissions=pm.PortalMask.ToString();
							container.Security.Roles.Add(role);
						}
					}
				}
			}
			Hashtable ht=new Hashtable();
			if(null!=thisWeb)
			{
				if(null!=web.Theme)
				{
					if(web.Theme.Length>0)
						ht.Add("Theme",web.Theme);
				}
				if(web.AllowUnsafeUpdates)
					ht.Add("AllowUnsafeUpdates",web.AllowUnsafeUpdates);
				if(null!=web.AlternateHeader)
				{
					if(web.AlternateHeader.Length>0)
						ht.Add("AlternateHeader",web.AlternateHeader);
				}
			}
						
			if(ht.Count>0)
			{

				DictionarySerializer DS = new DictionarySerializer(ht);
				XmlSerializer xmlser=new XmlSerializer(typeof(DictionarySerializer ),"SPFile.Props");

				MemoryStream writer = new MemoryStream();// StreamWriter("c:\\11.xml");

				xmlser.Serialize(writer,DS);
				writer.Flush();
				writer.Seek(0,SeekOrigin.Begin);

				TextReader tr=new StreamReader(writer);
						
				container.PropertyBag=tr.ReadToEnd();
			}
			
			if(ProcessSPArea(container,thisArea,"\\",listName,folderName,includeSubWebs,extractUsers,extractDesign,threshold,extractVersions,excludedProperties))
				rootContainer.Containers.Add(container);
			Directory.SetCurrentDirectory(outputDirectory);
			
			
			//Validate the schema prior to saving
			if(!import.Validate())
			{
				Logger.Log(ErrorLevel.Information,"Validation failed, last error: "+import.LastError);
				Console.ReadLine();
			}
			else
			{
				try
				{
					import.Serialize("struct.xml");
				}
				catch(SPExportException ex)
				{
					Logger.Log(ErrorLevel.Information,"Exception occurred: "+ex.Message);
				}
				try
				{
					listtemplates.Serialize("listtemplates.xml");
				}
				catch(SPExportException ex)
				{
					Logger.Log(ErrorLevel.Information,"Exception occurred: "+ex.Message);
				}

			}

			return nrOfDocuments.ToString()+"-"+nrOfListItems.ToString();
		}
		private bool ProcessSPAreaListings(Container Container, Area Area, string Relative)
		{
			string curDir=Directory.GetCurrentDirectory();
			bool returnValue=true;
			try
			{
				AreaListingCollection listings = Area.Listings;
				if(listings.Count>0)
				{
					DataContainer dataContainer=new DataContainer();
					dataContainer.Name="Listings";
					dataContainer.Operation=Verbs.modify;
					dataContainer.Template="Listings";
					dataContainer.BaseTemplate="Listings";
					dataContainer.RelativeitemXML=Relative+"listings.xml"; //This is the path to the file with the items
					Container.DataContainers.Add(dataContainer);
					List list=new List();
					
					
					Profile profile=new Profile();
					profile.Name="Listings";
					list.Profiles.Add(profile);
					
					foreach(AreaListing listing in listings)
					{
						Item item=new Item();
						Itemfield field=new Itemfield("Title",FieldType.Text,listing.Title);
						item.Fields.Add(field);
						field=new Itemfield("Description",FieldType.Note,listing.Description);
						item.Fields.Add(field);
						field=new Itemfield("Type",FieldType.Text,listing.Type.ToString());
						item.Fields.Add(field);
						field=new Itemfield("Author",FieldType.Text,listing.CreatedBy);
						item.Fields.Add(field);
						field=new Itemfield("Created",FieldType.DateTime,listing.CreationDate.ToString());
						item.Fields.Add(field);
						field=new Itemfield("Editor",FieldType.Text,listing.LastModifiedBy);
						item.Fields.Add(field);
						field=new Itemfield("Modified",FieldType.DateTime,listing.LastModified.ToString());
						item.Fields.Add(field);
						field=new Itemfield("URL",FieldType.Text,listing.URL);
						item.Fields.Add(field);

						profile.Items.Add(item);
	
					}
					list.Serialize(curDir+"\\listings.xml");
				}
			}
			catch(Exception Ex)
			{
				Logger.Log(ErrorLevel.Error,"Errors when saving the portal listings. Error: "+Ex.Message);
				returnValue=false;
			}
			return returnValue;


		}
        private bool ProcessSPArea(Container Container, Area area, string Relative, string List, string Folder, bool IncludesubAreas, bool ExtractUsers, bool ExtractDesign, DateTime Threshold, bool ExtractVersions, Hashtable excludedProperties)
		{
			thisWeb=area.Web;
			bool returnValue=false;
			SPDocumentLibrary doclib=null;
            Hashtable renamedFields = new Hashtable();
			if(null!=thisWeb)
				thisWeb.Lists.IncludeRootFolder=true;
			string currentDirectory=Directory.GetCurrentDirectory();
			ProcessSPAreaListings(Container,area,Relative);
			if(IncludesubAreas)
			{

				foreach(Area subArea in area.Areas)
				{
					Container subAreaContainer=new Container();

					string cleanTitle = subArea.Title;
					subAreaContainer.Name=subArea.Title;
					subAreaContainer.Owner=subArea.Owner;
					subAreaContainer.Contact=subArea.OwnerEmail;
					subAreaContainer.Description=subArea.Description;
					subAreaContainer.Type=Container.Type;
					subAreaContainer.Template =subArea.AreaTemplate;
					Directory.CreateDirectory(cleanTitle);
					Directory.SetCurrentDirectory(cleanTitle);
					Logger.Log(ErrorLevel.Information,"Processing Subarea "+subArea.Title);

					Hashtable ht=new Hashtable();
					if(null!=thisWeb)
					{
						if(null!=thisWeb.Theme)
						{
							if(thisWeb.Theme.Length>0)
								ht.Add("Theme",thisWeb.Theme);
						}
						if(thisWeb.AllowUnsafeUpdates)
							ht.Add("AllowUnsafeUpdates",thisWeb.AllowUnsafeUpdates);
						if(null!=thisWeb.AlternateHeader)
						{
							if(thisWeb.AlternateHeader.Length>0)
								ht.Add("AlternateHeader",thisWeb.AlternateHeader);
						}
					}
						
					if(ht.Count>0)
					{

						DictionarySerializer DS = new DictionarySerializer(ht);
						XmlSerializer xmlser=new XmlSerializer(typeof(DictionarySerializer ),"SPFile.Props");

						MemoryStream writer = new MemoryStream();// StreamWriter("c:\\11.xml");

						xmlser.Serialize(writer,DS);
						writer.Flush();
						writer.Seek(0,SeekOrigin.Begin);

						TextReader tr=new StreamReader(writer);
						
						subAreaContainer.PropertyBag=tr.ReadToEnd();
					}
						


					if(ProcessSPArea(subAreaContainer,subArea,Relative+cleanTitle+"\\",List,Folder,IncludesubAreas,ExtractUsers,ExtractDesign,Threshold,ExtractVersions,excludedProperties))
						Container.Containers.Add(subAreaContainer);
					Directory.SetCurrentDirectory(currentDirectory);
					thisWeb=area.Web;
				
				}
			}
			
			if(null!=thisWeb)
			{
				SPListTemplateCollection templates=area.Web.ListTemplates;
				thisWeb.IncludeSupportingFolders=true;
				thisWeb.Lists.IncludeRootFolder=true;

				//Add lists and libraries
				foreach(SPList spList in thisWeb.Lists)
				{
					if(List.Length>0)
					{
						//If the list parameter was specified extract only that one
						if(spList.Title!=List) 
							continue;
					}
					Logger.Log(ErrorLevel.Information,"Processing list "+spList.Title);

					bool Docs=false;
					if(spList.BaseType==SPBaseType.DocumentLibrary)
					{
						Docs=true;
						doclib=(SPDocumentLibrary)spList;
					}
					if(spList.BaseTemplate==SPListTemplateType.PictureLibrary)
					{
						Docs=true;
						doclib=(SPPictureLibrary)spList;
					}
					if(Folder.Length>0 && !Docs)
					{
						Logger.Log(ErrorLevel.Error,"Cannot extract a folder from a list");
						return false;
					}

					string cleanTitle = Miscallaneous.FixName(spList.Title);
					string templateName=spList.Title+" template for "+area.Title;
					Directory.CreateDirectory(cleanTitle);
					Directory.SetCurrentDirectory(cleanTitle);
					SharePoint.ImportExport.Core.DataContainer dataContainer=new DataContainer();
					dataContainer.Name=spList.Title;
					dataContainer.Type=DataContainerType.Library;
					dataContainer.Template=templateName;
					dataContainer.BaseTemplate=spList.BaseTemplate.ToString();
					dataContainer.WebPart=true;
					dataContainer.QuickLaunch=spList.OnQuickLaunch;    
					dataContainer.RelativeitemXML=Relative+cleanTitle+"\\items.xml"; //This is the path to the file with the items


					if(spList.BaseTemplate==SPListTemplateType.ListTemplateCatalog || spList.BaseTemplate==SPListTemplateType.WebPartCatalog || spList.BaseTemplate==SPListTemplateType.WebTemplateCatalog)
					{
						dataContainer.Template=spList.BaseTemplate.ToString();
						templateName=dataContainer.Template;
					}
					else
					{
						/* Create a new instance of the ListTemplate class and add it to the ListTemplate collection */
						ListTemplate listTemplate= new ListTemplate();

						listtemplates.ListTemplates.Add(listTemplate); //Don't add the base catalog lists as templates

						listTemplate.NameAttribute=templateName;
				
						listTemplate.Name=templateName;
						listTemplate.Title=templateName;
						listTemplate.BaseType=spList.BaseTemplate.ToString();
						listTemplate.Description=spList.Description;
						if(Docs || spList.BaseTemplate==SPListTemplateType.Survey)
							listTemplate.EnableAttachments=false;
						else
							listTemplate.EnableAttachments=spList.EnableAttachments;
						if(Docs)
							listTemplate.EnableVersioning=spList.EnableVersioning;
						else
							listTemplate.EnableVersioning=false;
						foreach(SPField newField in spList.Fields)
						{
							Field f=new Field();
							;
							f.Displayname=newField.Title;
							f.AddToDefaultView=false;
							f.Extendedtype=(FieldType)Enum.Parse(typeof(FieldType),newField.TypeAsString,true);
							f.GroupBy=false;
							f.Required=newField.Required;
							f.Xml=newField.SchemaXml.Replace(f.Name,XmlConvert.DecodeName(newField.InternalName));
                            f.Name = XmlConvert.DecodeName(newField.InternalName);
					
							switch(newField.TypeAsString)
							{
								case "Calculated":
									SPFieldCalculated fCalc=(SPFieldCalculated)newField;
									f.PropertyValues.Add(fCalc.DefaultFormula);
									break;
								case "Choice":
									SPFieldChoice fc= (SPFieldChoice)newField;
									foreach(string choice in fc.Choices)
										f.PropertyValues.Add(choice);
									break;
								case "GridChoice":
								{
									SPFieldRatingScale fgc= (SPFieldRatingScale)newField;
									f.PropertyValues.Add(fgc.GridEndNumber.ToString());
									if(null!=fgc.GridNAOptionText)
										f.PropertyValues.Add(fgc.GridNAOptionText.ToString());
									else
										f.PropertyValues.Add(String.Empty);
									f.PropertyValues.Add(fgc.GridStartNumber.ToString());
									if(null!=fgc.GridTextRangeAverage)
										f.PropertyValues.Add(fgc.GridTextRangeAverage);
									else
										f.PropertyValues.Add(String.Empty);
									if(null!=fgc.GridTextRangeHigh)
										f.PropertyValues.Add(fgc.GridTextRangeHigh);
									else
										f.PropertyValues.Add(String.Empty);
									if(null!=fgc.GridTextRangeLow)
										f.PropertyValues.Add(fgc.GridTextRangeLow);
									else
										f.PropertyValues.Add(String.Empty);



									break;
								}
								case "MultiChoice":
									SPFieldMultiChoice fmc= (SPFieldMultiChoice)newField;
									foreach(string choice in fmc.Choices)
										f.PropertyValues.Add(choice);
									break;
								case "Note":
									f.Richtext=true;
									break;
							}
							listTemplate.Fields.Add(f);
						}
						if(Folder.Length==0) //No use extracting views for just a folder
						{
							foreach(SPView spView in spList.Views)
							{
								string query="";
								if(spView.Query==null)
									query="";
								else
									query=spView.Query;

								//Don't move the explorer view
								if(spView.Url.ToLower().EndsWith("/webfldr.aspx"))
									continue;

								Logger.Log(ErrorLevel.Information,"Adding the view: "+spView.Title);

								View view=new View();
								view.Name=spView.Title;
								view.Query=query;
								view.Hidden=spView.Hidden;
								foreach(string s in spView.ViewFields)
								{
									view.ViewFields.Add(s);
						
								}
								view.DefaultView=spView.DefaultView;
								//dataContainer.Views.Add(view);
								//Add the view to the template
								listTemplate.Views.Add(view);
							}
						}
						Hashtable ht=new Hashtable();
						if(null!=spList.Direction)
						{
							if(spList.Direction.Length>0 && spList.Direction!="none")
								ht.Add("Direction",spList.Direction);
						}
						if(spList.Ordered)
						{
							ht.Add("Ordered",spList.Ordered);
						}
						if(null!=spList.EventSinkAssembly)
						{
							if(spList.EventSinkAssembly.Length>0)
								ht.Add("EventSinkAssembly",spList.EventSinkAssembly);
						}
						if(null!=spList.EventSinkClass)
						{
							if(spList.EventSinkClass.Length>0)
								ht.Add("EventSinkClass",spList.EventSinkClass);
						}
						if(null!=spList.EventSinkData)
						{
							if(spList.EventSinkData.Length>0)
								ht.Add("EventSinkData",spList.EventSinkData);
						}
						if(Docs && spList.EnableVersioning)
						{
							ht.Add("EnableVersioning",spList.EnableVersioning);
						}
						if(spList.EnableModeration)
						{
							ht.Add("EnableModeration",spList.EnableModeration);
						}
						if(!Docs && spList.EnableAttachments)
						{
							ht.Add("EnableAttachments",spList.EnableAttachments);
						}
						if(spList.BaseTemplate==SPListTemplateType.Survey)
						{
							if(!spList.ShowUser)
							{
								ht.Add("ShowUser",spList.ShowUser);
							}
							if(!spList.AllowMultiResponses)
							{
								ht.Add("AllowMultiResponses",spList.AllowMultiResponses);
							}
						}


						if(ht.Count>0)
						{

							DictionarySerializer DS = new DictionarySerializer(ht);
							XmlSerializer xmlser=new XmlSerializer(typeof(DictionarySerializer ),"SPFile.Props");

							MemoryStream writer = new MemoryStream();// StreamWriter("c:\\11.xml");

							xmlser.Serialize(writer,DS);
							writer.Flush();
							writer.Seek(0,SeekOrigin.Begin);

							TextReader tr=new StreamReader(writer);
						
							listTemplate.PropertyBag=tr.ReadToEnd();
						}

					}


					//Create a new list object that will contain the actual items
					List list = new List();
					Profile profile = new Profile();
					profile.Name=dataContainer.Template;
					profile.Hidden=spList.Hidden;
					list.Profiles.Add(profile);
					int i=0;
					if(Docs)
					{
						int nDocs=0;
						try
						{
							SPFolder folder=doclib.RootFolder;
                            nDocs = SharedCode.ProcessSPFolder(Container, dataContainer, folder, profile, Folder, Threshold, ExtractVersions, Relative, excludedProperties, spList.RootFolder.Name, renamedFields);
						}
						catch(Exception Ex)
						{
							Logger.Log(ErrorLevel.Error,"Exception when processing the list "+dataContainer.Name+". Error: "+Ex.Message);
						}

						
						if(nDocs>=0)
						{
							nrOfDocuments+=nDocs;
							Container.DataContainers.Add(dataContainer);
						}
					}
					else
					{

						SPListItemCollection items=spList.Items;
						if(Threshold!=DateTime.MinValue)
						{
							SPQuery query=new SPQuery();
							query.Query=String.Format("<Where><Gt><FieldRef Name='Modified'/>" +
								"<Value Type='DateTime' StorageTZ='TRUE'>{0}</Value></Gt></Where>",
								SPUtility.CreateISO8601DateTimeFromSystemDateTime(Threshold.ToUniversalTime()));
							items=spList.GetItems(query);
						}

						foreach(SPListItem spitem in items)
						{
							i++;
							Item item=new Item();
							nrOfListItems++;

							// not all lists have Attachements defined, skip if it fails
							try
							{
								SPAttachmentCollection attachments = spitem.Attachments;

								for (int ia=0; ia<attachments.Count; ia++)
								{
									
									string s=attachments.UrlPrefix +attachments[ia];
									SPFile srcFile = area.Web.GetFile(s);
									string fileName = srcFile.Name;

									Guid g=new Guid();
									g=Guid.NewGuid();
									
									GotDotNet.SharePointExtractor.Common.SharedCode.OpenBinary(g.ToString("D")+".bin", srcFile);

									Attachment att=new Attachment(fileName,g.ToString()+".bin");
									item.Attachments.Add(att);
								}
							}
							catch
							{
							}

							foreach(SPField field in spitem.Fields)
							{
								// **need to handle
								if(field.Type==SPFieldType.Counter)
									continue;
								if(field.Type==SPFieldType.File)
									continue;
								if(field.Type==SPFieldType.Attachments)
									continue;
								if(field.Type==SPFieldType.Calculated)
									continue;
								if(field.Hidden||field.ReadOnlyField)
									continue;
								if(field.InternalName=="FileLeafRef")
									continue;
								string Value="";
								try
								{
									Value=spitem[field.InternalName].ToString();
								}
								catch
								{
								}
								if(Value.Length>0)
								{
									if(field.Type==SPFieldType.User)
									{
										Value = SharedCode.GetUserValue(Value, area.Web);
									}
									Itemfield itf=new Itemfield(XmlConvert.DecodeName(field.InternalName),(FieldType)Enum.Parse(typeof(FieldType),field.TypeAsString,true),Value);
									item.Fields.Add(itf);
								}
							}

							profile.Items.Add(item);
						}
						Container.DataContainers.Add(dataContainer);
					}
					try
					{
						list.Serialize("items.xml");
						returnValue=true;
					}
					catch(SPExportException ex)
					{
						Logger.Log(ErrorLevel.Information,"Exception occurred: "+ex.Message);
						returnValue=false;
					}
					Directory.SetCurrentDirectory(currentDirectory);
				}
						
				// add the design elements
				if(ExtractDesign)
					SharedCode.ProcessDesignFolder(Container,null,area.Web,Relative);
			}

			return returnValue;

		}
		


	}
}

